#include "sensertools.h"
#include "ui_sensertools.h"

SenserTools::SenserTools(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::SenserTools)
{
    ui->setupUi(this);

    uart_port_ = nullptr;

    // 获取共享数据单列
    DataSingleton *share_data = DataSingleton::GetInstace();
    share_data->ui = ui;

    // 设置MainWindow的标题
    setWindowTitle("QT工具");
    // 获取串口信息
    getSerailInfo();
    // 设置波特率选项
    setBaudInfo();

    // 设置串口页面
    ui->seraicbt->setEnabled(false);

    // 设置device选择页面
    setDeviceNameInfo();
//    setDeviceTypeInfo();
    connect(ui->devicecomboBox, QOverload<const QString &>::of(&QComboBox::textActivated), this, &SenserTools::setDeviceTypeInfo);

    // 移动serail_op_到线程
    serail_op_.moveToThread(&serail_work_thread_);

    // 关联MainWidow和Serial的信号
    // 使用事件循环将信号和槽函数的调用放入接收对象所在的线程的事件队列中
    connect(this, &SenserTools::openSerialPort, &serail_op_, &SerialOp::openSerialPort, Qt::QueuedConnection);
    connect(this, &SenserTools::setSerailParams, &serail_op_, &SerialOp::setSerailParams, Qt::QueuedConnection);
    // 关联串口打开结果和显示
    connect(&serail_op_, &SerialOp::onSerialPortOpenResult, this, &SenserTools::onSerialPortOpenResult, Qt::QueuedConnection);

//    connect(ui->mytestbt, &QPushButton::clicked, &serail_op_, &SerialOp::setDefaultParms, Qt::QueuedConnection);
    // 直接连接信号和槽函数，即在同一线程中直接调用槽函数
    connect(&serail_work_thread_, &QThread::finished, &serail_op_, &SerialOp::closeSerialPort, Qt::DirectConnection);
    // 关联串口信息和显示
    connect(&serail_op_, &SerialOp::uartDataTextShow, this, &SenserTools::uartDataTextShow, Qt::QueuedConnection);

    // 关联打开串口的槽函数
    connect(ui->seraiobt, &QPushButton::clicked, [&]() {
        // 判断串口是否为空
        if (ui->portcomboBox->currentText().isEmpty() | ui->devtype_comboBox->currentText().isEmpty()) {
            QMessageBox::warning(this, "警告", "请选择串口和器件型号！");
            return;
        }

        // 判断当前选择的器件设置切换的功能页面

        // 清除串口日志
        ui->serailDataShow->clear();

        // 发送信号创建串口
        emit openSerialPort(ui->portcomboBox->currentText());

        // 通过invokeMethod发送信号创建串口并获取返回值,需要是Qt::DirectConnection
        // bool ret = false;
        // QMetaObject::invokeMethod(&serail_op_, "openSerialPort",
        //                          Qt::DirectConnection,
        //                          Q_RETURN_ARG(bool, ret),
        //                          Q_ARG(QString, ui->portcomboBox->currentText()));
        // if (ret == false) {
        //     QMessageBox::warning(this, "警告", "串口打开失败！");
        //     return; 
        // } else {
        //     ui->seraiobt->setEnabled(false);
        //     ui->seraicbt->setEnabled(true);
        // }

        // 启动线程
        serail_work_thread_.start();

        qDebug() << "串口打开成功！";

    });

    // 关联关闭串口的槽函数
    connect(ui->seraicbt, &QPushButton::clicked, [&]() {
        // 请求线程退出
        serail_work_thread_.quit();
        // 给一个超时时间等待线程结束
        if (!serail_work_thread_.wait(1000)) {
            // 如果超时还没结束，强制终止
            serail_work_thread_.terminate();
            serail_work_thread_.wait();
        }

        ui->seraiobt->setEnabled(true);
        ui->seraicbt->setEnabled(false);
    });
}

void SenserTools::onSerialPortOpenResult(bool success)
{
    if (success) {
        // 串口打开成功，设置串口参数
        emit setSerailParams(ui->baudcomboBox->currentText().toInt(), 
                           QSerialPort::Data8, 
                           QSerialPort::NoParity,
                           QSerialPort::OneStop, 
                           QSerialPort::NoFlowControl);
        
        ui->seraiobt->setEnabled(false);
        ui->seraicbt->setEnabled(true);
    } else {
        QMessageBox::warning(this, "警告", "串口打开失败！");
        // 请求线程退出
        serail_work_thread_.quit();
        // 给一个超时时间等待线程结束
        if (!serail_work_thread_.wait(1000)) {
            // 如果超时还没结束，强制终止
            serail_work_thread_.terminate();
            serail_work_thread_.wait();
        }
    }
}

void SenserTools::getSerailInfo()
{
    // 获取串口信息
    if (QSerialPortInfo::availablePorts().count() > 0)
    {
        ui->portcomboBox->setMinimumContentsLength(0);
        ui->portcomboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);

        for (int i = 0; i < QSerialPortInfo::availablePorts().count(); i++)
        {
            ui->portcomboBox->addItem(QSerialPortInfo::availablePorts().at(i).portName());
        }
    }
}

void SenserTools::setBaudInfo()
{
    // 设置波特率选项
    if (!ui->portcomboBox->currentText().isEmpty()) {
        ui->baudcomboBox->addItem("115200");
        ui->baudcomboBox->addItem("57600");
        ui->baudcomboBox->addItem("19200");
        ui->baudcomboBox->addItem("38400");
        ui->baudcomboBox->addItem("9600");
    }
}

void SenserTools::setDeviceNameInfo()
{
    ui->devicecomboBox->setMinimumContentsLength(0);
    ui->devicecomboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
    ui->devicecomboBox->addItem("毫米波雷达");
    ui->devicecomboBox->addItem("其他");
}

void SenserTools::setDeviceTypeInfo()
{
    ui->devtype_comboBox->clear();
    qDebug() << ui->devicecomboBox->currentText();
    if (ui->devicecomboBox->currentText() == "毫米波雷达") {
        ui->devtype_comboBox->addItem("CEM5825");
        ui->devtype_comboBox->addItem("其他");
    } else if (ui->devicecomboBox->currentText() == "其他") {
        ui->devtype_comboBox->addItem("其他");
        ui->devtype_comboBox->addItem("其他");
    }
}

void SenserTools::uartDataTextShow(QString str)
{
    // 显示串口信息
    ui->serailDataShow->append(str);

}

SenserTools::~SenserTools()
{   
    serail_work_thread_.quit();
    serail_work_thread_.wait();

    delete ui;
}
